const path = require('path');
const ffmpeg = require('fluent-ffmpeg');
const ffmpegStatic = require('ffmpeg-static');
const fs = require('fs-extra');
const { getAllFilesInDirectory } = require('./fileUtils');

class VideoProcessor {
    constructor(app) {
        this.app = app;
        this._initializeFFmpeg();
    }

    // 初始化FFmpeg路径
    _initializeFFmpeg() {
        const ffmpegPath = ffmpegStatic.replace('app.asar', 'app.asar.unpacked');
        ffmpeg.setFfmpegPath(ffmpegPath);
        this.ffmpeg = ffmpeg;
    }

    async extractFromDir(taskId, dir, fps = 1, quality = 2) {
        try {
            // 支持更多的视频格式，如 .mp4, .mkv, .mov, .hevc 等
            const videoFiles = await getAllFilesInDirectory(dir, ['.mp4', '.mkv', '.mov', '.hevc', '.265'], ['workspace']);
            const outputDir = path.join(dir, 'frames');
            await this._prepareOutputDir(outputDir);
            this.processCallback(taskId, 'extract-start', dir);

            // 使用 Promise.all 来等待所有视频文件处理完成
            const processingPromises = videoFiles.map((videoPath) => {
                const videoName = path.basename(videoPath, path.extname(videoPath));
                return new Promise((resolve, reject) => {
                    this.ffmpeg(videoPath)
                        .outputOptions([`-vf fps=${fps}`, `-qscale:v ${quality}`])
                        .output(path.join(outputDir, `${videoName}_frame%04d.jpg`))
                        .on('start', (cmdline) => {
                            this.processCallback(taskId, 'process-start', videoPath);
                        })
                        .on('progress', (progress) => {
                            this.processCallback(taskId, 'frame-progress', `抽取${path.basename(videoPath)}： 第${progress.frames}帧`);
                        })
                        .on('end', async () => {
                            const frames = await this._getGeneratedFrames(outputDir);
                            this.processCallback(taskId, 'process-complete', `处理完成${videoName}!`);
                            resolve(frames);
                        })
                        .on('error', (err) => {
                            this.processCallback(taskId, 'process-error', err);
                            reject(err);
                        })
                        .run();
                });
            });

            // 等待所有视频文件处理完成
            const results = await Promise.all(processingPromises);
            const result_merge = results.flat();
            this.processCallback(taskId, 'extract-complete', result_merge);

            return result_merge;
        } catch (error) {
            throw this._handleError(error);
        }
    }

    /**
     * 视频抽帧核心方法
     * @param {string} videoPath 视频路径
     * @param {string} outputDir 输出目录
     * @param {number} fps 抽帧频率（每秒帧数）
     * @param {number} quality 图片质量（1-31）
     * @returns {Promise<string[]>} 生成的图片路径数组
     */
    async extractFromFile(taskId, videoPath, outputDir, fps = 1, quality = 2) {
        try {
            await this._prepareOutputDir(outputDir);
            const basename = path.basename(videoPath, path.extname(videoPath));
            return new Promise((resolve, reject) => {
                this.ffmpeg(videoPath)
                    .outputOptions([`-vf fps=${fps}`, `-qscale:v ${quality}`])
                    .output(path.join(outputDir, `${basename}_frame%04d.jpg`))
                    .on('start', (cmdline) => {
                        this.processCallback(taskId, 'process-start', cmdline);
                    })
                    .on('progress', (progress) => {
                        this.processCallback(taskId, 'frame-progress', progress.frames);
                    })
                    .on('end', async () => {
                        const frames = await this._getGeneratedFrames(outputDir);
                        this.processCallback(taskId, 'process-complete', frames);
                        resolve(frames);
                    })
                    .on('error', (err) => {
                        this.processCallback(taskId, 'process-error', err);
                        reject(err);
                    })
                    .run();
            });
        } catch (err) {
            throw this._handleError(err);
        }
    }

    processCallback(taskId, event, data) {
        this.app &&
            this.app.queue.enqueue(
                taskId,
                {
                    event: event,
                    data: data
                },
                false
            );
    }

    // 准备输出目录
    async _prepareOutputDir(outputDir) {
        await fs.ensureDir(outputDir);
        // await fs.emptyDir(outputDir);
    }

    // 获取生成的帧文件
    async _getGeneratedFrames(outputDir) {
        const files = await fs.readdir(outputDir);
        return files.filter((f) => f.match(/\.(jpg|png)$/i)).map((f) => path.join(outputDir, f));
    }

    // 错误处理
    _handleError(err) {
        console.error('[VideoProcessor]', err);
        return new Error(`视频处理失败: ${err.message}`);
    }
}

module.exports = { VideoProcessor };
